﻿using System;
using System.Collections.Generic;
using System.Text;

namespace InSilicio.Spatial
{
    /// <summary>
    /// A class representing an axis-aligned box partitioning 3D space (an octant!).
    /// </summary>
    public class Octant
    {
        #region Variables
        /// <summary>
        /// A list containing the contents of this octant.
        /// </summary>
        public List<Boundable> contents;
        /// <summary>
        /// An array of this octant's suboctants.
        /// </summary>
        public Octant[] subOctants;
        /// <summary>
        /// The axis-aligned 3D bounds of this octant.
        /// </summary>
        public AABB bounds;
        /// <summary>
        /// This octant's depth in the octree.
        /// </summary>
        public int depth;
        #endregion

        #region Properties
        /// <summary>
        /// Gets whether or not this octant is a leaf in the octree.
        /// </summary>
        public bool IsLeaf
        {
            get { return subOctants == null; }
        }
        #endregion

        /// <summary>
        /// Constructs an octant with the specified bounds.
        /// </summary>
        /// <param name="bounds">The bounds that this octant encompasses.</param>
        /// <param name="depth">This octant's depth in the octree.</param>
        public Octant(AABB bounds, int depth)
        {
            this.bounds = bounds ?? new AABB(new Point3f(), new Point3f());
            this.depth = depth;
            subOctants = null;
            contents = new List<Boundable>();
        }

        /// <summary>
        /// Tests whether or not this octant's bounds intersect the given Boundable.
        /// </summary>
        /// <param name="obj">The object to test against for intersection.</param>
        /// <returns>True if this octant intersects the Boundable object; false otherwise.</returns>
        public bool Intersects(Boundable obj)
        {
            return obj.intersects(bounds);
        }
    }
}
